import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';
import { InputMarkOptions } from '../../store';
import { Lnglat } from './input-mark.class';

@Component({
  selector: 'ege-input-mark',
  templateUrl: './input-mark.component.html',
  styleUrls: ['./input-mark.component.scss']
})
export class InputMarkComponent implements OnInit {

  simpleModel: boolean = false; 
  formGroup: FormGroup;

  @Output() ok: EventEmitter<InputMarkOptions> = new EventEmitter();
  @Output() cancel: EventEmitter<any> = new EventEmitter();

  constructor(
    private fb: FormBuilder,
  ) { }

  ngOnInit() {
    const initialValues = this.initFormGroupValues(this.simpleModel);
    this.formGroup = this.fb.group({});
    this.formBuilder(this.simpleModel, initialValues);
  }

  private formBuilder(simpleModel: boolean, values: any): void {
    let lng, lat;
    this.formGroup.removeControl('lng');
    this.formGroup.removeControl('lat');
    if(simpleModel) {
      lng = new FormControl(values.lng, [Validators.required, Validators.min(-180), Validators.max(180)]);
      lat = new FormControl(values.lat, [Validators.required, Validators.min(-90), Validators.max(90)]);
    } else {
      lng = this.fb.group({
        direction: [values.lng.direction],
        degrees: [values.lng.degrees, [Validators.required, Validators.min(0), Validators.max(180)]],
        minutes: [values.lng.minutes, [Validators.required, Validators.min(0), Validators.max(59)]],
        centiminutes: [values.lng.centiminutes, [Validators.required, Validators.min(0), Validators.max(59)]]
      });
      lng.valueChanges.subscribe(values => {
        const degrees: FormControl = lng.controls['degrees'];
        const minutes: FormControl = lng.controls['minutes'];
        const centiminutes: FormControl = lng.controls['centiminutes'];
        degrees.clearValidators();
        minutes.clearValidators();
        centiminutes.clearValidators();
        if(values.degrees === 180) {
          minutes.setValidators([Validators.required, Validators.min(0), Validators.max(0)]);
          centiminutes.setValidators([Validators.required, Validators.min(0), Validators.max(0)]);
        } else {
          minutes.setValidators([Validators.required, Validators.min(0), Validators.max(59)]);
          centiminutes.setValidators([Validators.required, Validators.min(0), Validators.max(59)]);
        }
        if(values.minutes > 0 || values.centiminutes > 0) {
          degrees.setValidators([Validators.required, Validators.min(0), Validators.max(179)]);
        } else {
          degrees.setValidators([Validators.required, Validators.min(0), Validators.max(180)]);
        }
      });
      lat = this.fb.group({
        direction: [values.lat.direction],
        degrees: [values.lat.degrees, [Validators.required, Validators.min(0), Validators.max(90)]],
        minutes: [values.lat.minutes, [Validators.required, Validators.min(0), Validators.max(59)]],
        centiminutes: [values.lat.centiminutes, [Validators.required, Validators.min(0), Validators.max(59)]]
      });
      lat.valueChanges.subscribe(values => {
        const degrees: FormControl = lat.controls['degrees'];
        const minutes: FormControl = lat.controls['minutes'];
        const centiminutes: FormControl = lat.controls['centiminutes'];
        degrees.clearValidators();
        minutes.clearValidators();
        centiminutes.clearValidators();
        if(values.degrees === 90) {
          minutes.setValidators([Validators.required, Validators.min(0), Validators.max(0)]);
          centiminutes.setValidators([Validators.required, Validators.min(0), Validators.max(0)]);
        } else {
          minutes.setValidators([Validators.required, Validators.min(0), Validators.max(59)]);
          centiminutes.setValidators([Validators.required, Validators.min(0), Validators.max(59)]);
        }
        if(values.minutes > 0 || values.centiminutes > 0) {
          degrees.setValidators([Validators.required, Validators.min(0), Validators.max(89)]);
        } else {
          degrees.setValidators([Validators.required, Validators.min(0), Validators.max(90)]);
        }
      });
    }
    this.formGroup.registerControl('lng', lng);
    this.formGroup.registerControl('lat', lat);
  }

  private initFormGroupValues(simpleModel: boolean): any {
    if(simpleModel) {
      return { lng: 0, lat: 0 };
    } else {
      return {
        lng: { direction: 'E', degrees: 0, minutes: 0, centiminutes: 0 },
        lat: { direction: 'N', degrees: 0, minutes: 0, centiminutes: 0 }
      };
    }
  }

  private switchValuesModel(values: any, simpleModel: boolean): any {
    const lnglat = new Lnglat(values.lng, values.lat);
    if(simpleModel) {
      return lnglat.toDMC();
    } else {
      return lnglat.toLnglat();
    }
  }

  modelSwitch(): void {
    const values = this.switchValuesModel(this.formGroup.value, this.simpleModel);
    this.simpleModel = !this.simpleModel;
    this.formBuilder(this.simpleModel, values);
  }

  onSubmit():void {
    const values = this.formGroup.value;
    const lnglat = new Lnglat(values.lng, values.lat);
    this.ok.emit(<InputMarkOptions>lnglat.toLnglat());
    this.onReset();
  }

  onReset():void {
    const values = this.initFormGroupValues(this.simpleModel);
    this.formGroup.reset(values);
  }

  onCancel():void {
    this.onReset();
    this.cancel.emit();
  }

}
